package tech.abing.spider.task.pageprocessor;

import java.net.InetAddress;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import tech.abing.spider.component.PageProcessor;
import tech.abing.spider.component.PageScript;
import tech.abing.spider.constants.FinalConstants;
import tech.abing.spider.model.Proccessable;
import tech.abing.spider.page.OkPage;
import tech.abing.spider.page.Page;
import tech.abing.spider.request.BasicRequest;
import tech.abing.spider.request.PageRequest;
import tech.abing.spider.request.StartContext;
import tech.abing.spider.task.model.CloseEntity;
import tech.abing.spider.task.model.PayLogClose;
import tech.abing.spider.task.model.PayRecord;
import tech.abing.spider.task.model.TaskTrade;
import tech.abing.spider.util.DateUtils;
import tech.abing.spider.util.RedisUtil;
import tech.abing.spider.util.StringUtils;
import tech.abing.spider.util.SysUtil;

public class PayLogProccessor2 implements PageProcessor {

	private static Logger logger = Logger.getLogger(PayLogProccessor2.class);
	
	static Pattern normalContain = Pattern.compile("天猫");

	@Override
	public PageScript getJavaScript() {
		return null;
	}

	@Override
	public Pattern getNormalContain() {
		return normalContain;
	}

	@Override
	public void process(OkPage page, StartContext context, List<BasicRequest> queue, List<Proccessable> objectContainer)
			throws Exception {
		
		String json = page.getContent();
		Document doc = null;
		JSONObject jsonObject = null;
		String temp = json.substring(json.indexOf("(") + 1, json.lastIndexOf(")"));
		jsonObject = JSONObject.fromObject(temp);

		String itemId = page.getRequest().getParamsByName("itemId").toString();
		String shopId = page.getRequest().getParamsByName("shopId").toString();
		String type = page.getRequest().getParamsByName("type").toString();
		String catchDate = page.getRequest().getParamsByName("catchDate").toString();
		String lastDate = page.getRequest().getParamsByName("lastDate").toString();
		String monthSale = page.getRequest().getParamsByName("monthSale").toString();

		if (jsonObject.containsKey("html")) {
			
			logger.info("=========>天猫成功返回数据");
			doc = Jsoup.parse(jsonObject.getString("html"));

			//
			String nickName = "";
			String rank = "";
			String level = "";
			String payDate = "";
			String payTime = "";
			String maxPayDate = null;
			String maxPayTime = null;

			Elements eles = null;
			PayRecord payRecord = null;
			if (temp.contains("成交记录")) {
				eles = doc.select("table tbody tr");
				for (Element e : eles) {
					if (e.select("td").size() > 0) {
						
						payDate = e.select("td[class=dealtime] p[class=date]").text();
						payTime = e.select("td[class=dealtime] p[class=time]").text();
						
						if (DateUtils.compareDate(payDate + " " + payTime, lastDate) == -1) {//不需要抓取
							return;
						}
						
						payRecord = new PayRecord();
						
						payRecord.setShopId(shopId);
						payRecord.setPrdNo(itemId);

						payRecord.setMonthSale(monthSale);

						nickName = e.select("td[class*=buyer] div[class=line]").first().text();
						if(StringUtils.isNotBlank(nickName) && nickName.indexOf("(") > -1){
							nickName = nickName.substring(0, nickName.indexOf("(")).trim();
						}
						payRecord.setNickName(nickName);
						try {
							rank = e.select("td[class*=buyer] img[class=rank]").last().attr("title");
						} catch (Exception e1) {
						}
						if (rank.indexOf("个") != -1) {
							rank = rank.substring(0, rank.indexOf("个"));
						}
						payRecord.setRank(rank);
						level = e.select("td[class*=buyer] div[class=line] a").attr("title");
						if (level.indexOf("会") != -1) {
							level = level.substring(0, level.indexOf("会"));
						}
						payRecord.setLevel(level);

						payRecord.setNum(e.select("td[class=quantity]").text());
						
						if (maxPayDate == null) {
							maxPayDate = payDate;
							maxPayTime = payTime;
						}
						payRecord.setPayDate(payDate);
						payRecord.setPayTime(payTime);
						payRecord.setSku(e.select("td[class*=style]").text());

						payRecord.setMaxPayDate(maxPayDate);
						payRecord.setMaxPayTime(maxPayTime);
						payRecord.setType(type);
						payRecord.setCatchDate(DateUtils.getDateTime());
						objectContainer.add(payRecord);
					}
				}
				
				//最多只能抓取100页
				int curPage = StringUtils.toInteger(doc.select("span.page-cur").text());
				if(curPage == 100){
					return;
				}
				
				Element nextEle = doc.select("span:contains(下一页)").parents().first();
				
				if(nextEle != null && "a".equals(nextEle.tagName())){//有下一页
					String nextUrl = "https:" + nextEle.attr("href");
					
					nextUrl = nextUrl + "&callback=jsoup";
					
					PageRequest req = context.createPageRequest(nextUrl, PayLogProccessor2.class, 1);
					req.putParams("itemId", itemId);
					req.putParams("shopId", shopId);
					req.putParams("type", type);
					req.putParams("catchDate", catchDate);
					req.putParams("lastDate", lastDate);
					req.putParams("monthSale", monthSale);

					//req.putParams("cookie", SysUtil.getValue("trade.cookie"));
					 //req.putParams("cookie", StringUtils.getRandomCookie());
					 req.putParams("cookie", StringUtils.toString(context.getContextAttribute("cookie")));
					req.putParams("referer", "https://item.taobao.com/item.htm?id=" + itemId);

					req.setUseJsoup(true);
					queue.add(req);// 跟进队列
				}
				
			}
			
		} else {// 被盯上了
			
			//立即返回到redis中
			RedisUtil redisUtil = (RedisUtil)context.getContextAttribute("redisUtil");
			
			//这里catchDate不能用当前时间，因为没有采集成功，下一次采集需要根据catchDate来判断
			TaskTrade taskTrade = new TaskTrade(itemId, shopId, type, lastDate, catchDate, monthSale);

			AtomicInteger atomicInteger = (AtomicInteger)context.getContextAttribute("atomicInteger");
			int count = atomicInteger.incrementAndGet();
			
			CloseEntity closeEntity = new CloseEntity();
			closeEntity.setCloseTime(DateUtils.getDateTime());
			closeEntity.setCount(count);
			
			InetAddress netAddress = InetAddress.getLocalHost();  
			closeEntity.setHostIp(netAddress.getHostAddress());
			closeEntity.setHostName(netAddress.getHostName());

			closeEntity.setProdId(itemId);
			closeEntity.setUrl(page.getRequest().getUrl());
			
			PayLogClose plc = new PayLogClose();
			plc.setTaskTrade(taskTrade);
			plc.setCloseEntity(closeEntity);
			
			String unsaleTask = SysUtil.getValue("redis.task_trade_product_id_unsale");
			String normalTask = SysUtil.getValue("redis.task_trade_product_id_normal");
			String hotTask = SysUtil.getValue("redis.task_trade_product_id_hot");
			
			String closeTask = SysUtil.getValue("redis.close_product_id");
			
				
			TaskTrade tt = plc.getTaskTrade();
			
			int monthSaleInt = StringUtils.toInteger(tt.getMonthSale());
			
			if(monthSaleInt >= FinalConstants.PRODUCT_HOT_SALE_MIN){//热销
				
				//push到制定队列中
				try {
					redisUtil.rpush(tt, hotTask);
					logger.info("访问受限，产品ID["+tt+"]入队队头["+hotTask+"]成功");
				} catch (Exception e) {
					e.printStackTrace();
					logger.error("访问受限，产品ID["+tt+"]入队队头["+hotTask+"]失败", e);
				}
				
			}else if(monthSaleInt >= FinalConstants.PRODUCT_NORMAL_SALE_MIN && monthSaleInt < FinalConstants.PRODUCT_HOT_SALE_MIN){//普通
				
				//push到制定队列中
				try {
					redisUtil.rpush(tt, normalTask);
					logger.info("访问受限，产品ID["+tt+"]入队队头["+normalTask+"]成功");
				} catch (Exception e) {
					e.printStackTrace();
					logger.error("访问受限，产品ID["+tt+"]入队队头["+normalTask+"]失败", e);
				}
				
			}else if(monthSaleInt > FinalConstants.PRODUCT_UNSALE_SALE_MIN && monthSaleInt < FinalConstants.PRODUCT_NORMAL_SALE_MIN){//滞销
				
				//push到制定队列中
				try {
					redisUtil.rpush(tt, unsaleTask);
					logger.info("访问受限，产品ID["+tt+"]入队队头["+unsaleTask+"]成功");
				} catch (Exception e) {
					e.printStackTrace();
					logger.error("访问受限，产品ID["+tt+"]入队队头["+unsaleTask+"]失败", e);
				}
				
			}
			
			//访问受限的日志
			CloseEntity ct = plc.getCloseEntity();
			try {
				redisUtil.lpush(ct, closeTask);
				logger.info("访问受限，日志信息["+ct+"]入队["+closeTask+"]成功");
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("访问受限，日志信息["+ct+"]入队["+closeTask+"]失败", e);
			}
			
			logger.error("访问受限,等待"+FinalConstants.FORBID_WAIT_SECONDS+"秒");
			TimeUnit.SECONDS.sleep(FinalConstants.FORBID_WAIT_SECONDS);
			
		}

	}

	@Override
	public void processErrorPage(Page page, StartContext context,
			List<Proccessable> objectContainer) throws Exception {
		// TODO Auto-generated method stub
		
	}


}
